import logging
from logging.handlers import RotatingFileHandler

from flask import Flask
from flask import g
from flask import render_template
from flask import session

from info.utils.commons import do_index_class, user_login_data

"""导入csrf  当修改服务器资源的时候保护(post put delete dispatch)"""
from flask_wtf.csrf import CSRFProtect, generate_csrf

"""导入StrictRedis 以关联session和redis"""
from redis import StrictRedis
"""导入数据库"""
from flask_sqlalchemy import SQLAlchemy
"""导入redis"""
import redis
"""导入session"""
from flask_session import Session
"""导入配置类"""
from config import config_dict

"""创建全局变量db"""
db = SQLAlchemy()

redis_store = None
"""工厂方法  根据参数返回不同的app对象"""
def create_app(config_name):
	"""创建app对象"""
	app = Flask(__name__)

	"""通过config_name 获取配置类"""
	config = config_dict.get(config_name)
	"""调用日志 传递日志级别"""
	log_file(config.LEVEL)
	"""加载配置对象"""
	app.config.from_object(config)

	"""创建SQLALchemy对象，并关联app"""
	db.init_app(app)
	"""创建redis对象(decode_responses设置格式不变)"""
	global redis_store
	redis_store =redis.StrictRedis(host=config.REDIS_HOST,port=config.REDIS_PORT,decode_responses=True)
	"""初始化session并关联app"""
	Session(app)
	"""设置应用程序csrf保护状态"""
	CSRFProtect(app)
	"""导入首页蓝图对象"""
	from info.modules.index import index_blue
	"""注册index_blue蓝图对象到app"""
	app.register_blueprint(index_blue)
	"""导入蓝图对象"""
	from info.modules.passport import passport_blue
	"""注册passport_blue蓝图对象到app"""
	app.register_blueprint(passport_blue)
	"""导入蓝图对象"""
	from info.modules.news import news_blue
	"""注册passport_blue蓝图对象到app"""
	app.register_blueprint(news_blue)
	"""导入蓝图对象"""
	from info.modules.profile import profile_blue
	"""注册passport_blue蓝图对象到app"""
	app.register_blueprint(profile_blue)
	"""添加函数到过滤器列表中"""
	app.add_template_filter(do_index_class,"index_class")
	"""拦截用户的响应,通过after_request"""
	@app.after_request
	def after_request(resp):
		csrf_token = generate_csrf()
		resp.set_cookie("csrf_token",csrf_token)
		return resp
	# 对404页面进行统一返回 errorhandler
	@app.errorhandler(404)
	@user_login_data
	def page_not_found(e):
		data = {
			"user_info":g.user.to_dict() if g.user else None
		}
		return	render_template("news/404.html",data=data)

	return app

def log_file(level):
	# 设置日志的记录等级
	logging.basicConfig(level=level)  # 调试debug级
	# 创建日志记录器，指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
	file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 100, backupCount=10)
	# 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
	formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
	# 为刚创建的日志记录器设置日志记录格式
	file_log_handler.setFormatter(formatter)
	# 为全局的日志工具对象（flask app使用的）添加日志记录器
	logging.getLogger().addHandler(file_log_handler)